package com.ayf.payment.game.api.controller.paychannel;

import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.channel.jiabei.util.JbStringUtil;
import com.ayf.payment.game.api.channel.zhuofutong.util.SignUtils;
import com.ayf.payment.game.api.dto.platform.PaymentChannelDTO;
import com.ayf.payment.game.api.dto.platform.SubstitutePayConfigDTO;
import com.ayf.payment.game.api.dto.platform.pay.WanXiangPayConfigParamVO;
import com.ayf.payment.game.api.entity.Order;
import com.ayf.payment.game.api.type.OrderStatus;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.ayf.payment.game.api.wx.WxSendMsgUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import com.swwx.charm.zookeeper.exception.GetLockFailedException;
import com.swwx.charm.zookeeper.exception.ReleaseLockFailedException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author wwl
 * @description:
 * @date 2021/2/22 15:49
 */
@RequestMapping("/")
@RestController
public class ZhuoFuTongPayNotifyController extends BasePayNotifyController {
    @Autowired
    private WxSendMsgUtils wxSendMsgUtils;


    /**
     * 代付异步通知处理
     */
    @RequestMapping(value = "zftong/pay/paynotify")
    public void payNotify(HttpServletRequest request, HttpServletResponse response) {
        String orderNo = JbStringUtil.formatString(request.getParameter("mchRequestId"));
        super.agentPayNotifyAsync(request,response,orderNo);
    }

    @RequestMapping("v/zftong/pay/notify")
    public void notify(HttpServletRequest request, HttpServletResponse response) {
        String orderNo = JbStringUtil.formatString(request.getParameter("mchOrderNo"));  //商户订单号
        super.notifyAsync(request, response, orderNo);
    }

    @RequestMapping("v/zftong/pay/returns")
    public void returns(HttpServletRequest request, HttpServletResponse response) {

    }

    @Override
    protected void notifyAsyncBusinesExec(HttpServletRequest request, HttpServletResponse response,Object obj) {
        PrintWriter pw = null;
        String traceId = SnowFlakeUtils.getTraceId();
        String mchId = request.getParameter("mchId");
        String orderid = request.getParameter("mchOrderNo");
        String wuDiOrderNo = request.getParameter("wuDiOrderNo");
        String status = request.getParameter("status");
        String mchMoney = request.getParameter("mchMoney");
        String sign = request.getParameter("sign");
        String paySuccTime = request.getParameter("paySuccTime");
        LogPortal.info("{} 卓付通交易异步通知 参数：mchId[{}] mchOrderNo[{}] wuDiOrderNo[{}] status[{}] sign[{}] mchMoney[{}] paySuccTime[{}]", traceId, mchId, orderid, wuDiOrderNo, status, sign, mchMoney, paySuccTime);
        try {
                pw = response.getWriter();
                Order order = orderService.selectByMerchantOrderNo(orderid);
                if (Objects.nonNull(order)){
                    PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(order.getPayChannleId());
                    String KeyValue = paymentChannelDTO.getChannelKey();
                    Map<String, String> map = new HashMap<>();
                    map.put("mchId", mchId);
                    map.put("mchOrderNo", orderid);
                    map.put("mchMoney", mchMoney);
                    map.put("paySuccTime", paySuccTime);
                    map.put("status", status);
                    map.put("wuDiOrderNo", wuDiOrderNo);
                    String signStr=SignUtils.sign(map,KeyValue).toUpperCase();
                    LogPortal.info("{} 卓付通交易异步通知 验签signStr[{}]", traceId,signStr);
                    if(sign.equals(signStr)) {
                        OrderStatus orderStatus = OrderStatus.PROCESSING;
                        if ("2".equals(status)) {
                            orderStatus = OrderStatus.SUCCESS;
                        }
                        if (OrderStatus.PROCESSING.equals(order.getOrderStatus())) {
                            String XY_GAME_PAY_LOCK_FLAG = System.getenv("XY_GAME_PAY_LOCK_FLAG");
                            String orderLockName = "orderLock".concat(this.getClass().getSimpleName()).concat(XY_GAME_PAY_LOCK_FLAG).concat(orderid);
                            boolean orderLock = false;
                            try {
                                if (orderLock = distributedLock.getLock(orderLockName)) {
                                    Order order2 = orderService.selectByMerchantOrderNo(orderid);
                                    if (order2 != null && OrderStatus.PROCESSING.equals(order2.getOrderStatus())) {
                                        order.setOrderNo(wuDiOrderNo);
                                        order.setOrderStatus(orderStatus);
                                        orderService.paymentOrder(order, new JSONObject());
                                        if (OrderStatus.SUCCESS.equals(order.getOrderStatus())) {
                                            orderService.orderToGetWay(order);
                                            try {
                                                wxSendMsgUtils.rechargeSuccess(order);
                                            } catch (Exception e) {
                                                LogPortal.error("{} 卓付通交易异步通知 商户订单号[{}]CallBack 微信通知异常", e, traceId, orderid);
                                            }
                                        }
                                        pw.write("SUCCESS");
                                        pw.flush();
                                        return;
                                    }
                                }
                            } catch (GetLockFailedException e) {
                                LogPortal.error("{} >>> [DISTRIBUTED_LOCK_ACQUIRE_FAILED_ZK] 分布式锁获取失败,锁名称为:{}", orderid, orderLockName);
                                LogPortal.error("{} >>> {} 获取lock失败", e, orderid, orderLockName);
                            } catch (Exception e) {
                                LogPortal.error("{} >>> {} 任务执行出错 ", e, orderid, orderLockName);
                            } finally {
                                if (orderLock) {
                                    LogPortal.info(orderid + " >>> " + orderLockName + " finished.");
                                    try {
                                        distributedLock.releaseLock(orderLockName);
                                    } catch (ReleaseLockFailedException e) {
                                        LogPortal.error("{} >>> [DISTRIBUTED_LOCK_RELEASE_FAILED_ZK] 分布式锁释放失败,锁名称为:{}", orderid, orderLockName);
                                        LogPortal.error("{} >>> {} 释放失败", e, orderid, orderLockName);
                                    }
                                }
                            }
                        } else {
                            LogPortal.info("{} 卓付通交易异步通知 商户订单号[{}] 异步通知 不在更新订单状态：[{}]", traceId, orderid, order.getOrderStatus());
                        }
                    }else {
                        LogPortal.error("{} 卓付通交易异步通知 商户订单号[{}] 异步通知验签失败", traceId, orderid);
                    }
                    pw.write("FAIL");
                    pw.flush();
                } else {
                    pw.write("FAIL");
                    pw.flush();
                }
            } catch (Exception e) {
                LogPortal.error("{} 卓付通交易异步通知 商户订单号[{}] 验签业务逻辑处理失败，具体原因:{}", e, traceId,orderid,e.getMessage());
            }finally {
                if (pw != null)
                    pw.close();
            }
 }

    @Override
    protected void notifySyncBusinesExec(HttpServletRequest request, HttpServletResponse response) {

    }

    @Override
    protected void agentPayNotifyAsyncBusinesExec(HttpServletRequest request, HttpServletResponse response, Object obj) {
        String traceId = SnowFlakeUtils.getTraceId();
        LogPortal.info("{} 卓付通代付异步通知 开始处理",traceId);
        String mchRequestId = JbStringUtil.formatString(request.getParameter("mchRequestId"));
        PrintWriter pw = null;
        try {
            String code=request.getParameter("code");
            String mchId = JbStringUtil.formatString(request.getParameter("mchId"));
            String status = JbStringUtil.formatString(request.getParameter("status"));
            String requestId = JbStringUtil.formatString(request.getParameter("requestId"));
            String mchMoney = JbStringUtil.formatString(request.getParameter("mchMoney"));
            String paySuccTime = JbStringUtil.formatString(request.getParameter("paySuccTime"));
            String errorMsg = JbStringUtil.formatString(request.getParameter("errorMsg"));
            String sign = JbStringUtil.formatString(request.getParameter("sign"));
            LogPortal.info("{} 卓付通代付异步通知 参数：mchRequestId[{}] status[{}] mchId[{}] requestId[{}] mchMoney[{}] code[{}] paySuccTime[{}] errorMsg[{}] sign[{}]", traceId, mchRequestId, status, mchId, requestId, mchMoney, code, paySuccTime, errorMsg, sign);
            pw = response.getWriter();
            if (StringUtils.isEmpty(mchRequestId)) {
                LogPortal.error("{} 卓付通代付异步通知 商户订单号数值为空，不进行后续操作 商户订单号[{}]", traceId, mchRequestId);
                pw.write("FAIL");
                pw.flush();
                return;
            }
            if (StringUtils.isBlank(sign)) {
                LogPortal.error("{} 卓付通代付异步通知 渠道签名为空 商户订单号[{}]", traceId, mchRequestId);
                pw.write("FAIL");
                pw.flush();
                return;
            }
            if (StringUtils.isEmpty(status)) {
                LogPortal.error("{} 卓付通代付异步通知 订单状态为空，不进行后续操作 商户订单号[{}]", traceId, mchRequestId);
                pw.write("FAIL");
                pw.flush();
                return;
            }
            SubstitutePayConfigDTO substitutePayConfigDTO = substitutePayConfigService.getSubstitutePayConfigById(9);
            WanXiangPayConfigParamVO wanXiangPayConfigParamVO = substitutePayConfigDTO.getWanXiangPayConfigParamVO();
            Map<String, String> map = new HashMap<>();
            map.put("mchId", mchId);
            map.put("mchRequestId", mchRequestId);
            map.put("requestId", requestId);
            map.put("mchMoney", mchMoney);
            map.put("status", status);
            map.put("paySuccTime", paySuccTime);
            map.put("errorMsg", errorMsg);
            String signStr=SignUtils.sign(map,wanXiangPayConfigParamVO.getKey()).toUpperCase();
            if (!sign.equals(signStr)) {
                LogPortal.error("{} 卓付通代付异步通知 验签失败,渠道签名[{}],系统签名[{}] 商户订单号[{}]", traceId, sign, signStr, mchRequestId);
                pw.write("FAIL");
                pw.flush();
                return;
            }
            if (mchRequestId.startsWith("Y")) {
                merchantCashOutService.ZhuoFuTongPaymentOnBehalfOf(traceId, status.toUpperCase(), mchRequestId, errorMsg);
            } else {
                merchantPayOrderService.ZhuoFuTongPayNotify(traceId, status, mchRequestId, errorMsg);
            }
            pw.write("SUCCESS");
            pw.flush();
        } catch (Exception e) {
            LogPortal.error("{} 卓付通代付异步通知 业务逻辑处理失败，具体原因:{} 商户订单号[{}]", e, traceId, e.getMessage(), mchRequestId);
            pw.write("{} 卓付通代付异步通知 响应验签处理失败：" + e.getMessage());
            pw.flush();
        } finally {
            if (pw != null)
                pw.close();
        }
    }
}
